package com.scs.application.modules.price.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.consts.SerialKeys;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.flow.FlowContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UtilNum;
import com.scs.application.modules.base.entity.Matr;
import com.scs.application.modules.base.entity.MatrUnit;
import com.scs.application.modules.base.entity.Supplier;
import com.scs.application.modules.base.mapper.MatrMapper;
import com.scs.application.modules.base.service.MatrUnitService;
import com.scs.application.modules.base.service.PackTempletItemService;
import com.scs.application.modules.price.dto.AdjustBuildDTO;
import com.scs.application.modules.price.dto.AdjustBuildScpDTO;
import com.scs.application.modules.price.entity.AdjustStock;
import com.scs.application.modules.price.entity.Adjustment;
import com.scs.application.modules.price.entity.AdjustmentItem;
import com.scs.application.modules.price.mapper.AdjustmentItemMapper;
import com.scs.application.modules.price.mapper.AdjustmentMapper;
import com.scs.application.modules.price.service.AdjustStockService;
import com.scs.application.modules.price.service.AdjustmentItemService;
import com.scs.application.modules.price.service.AdjustmentService;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.properties.HisConfig;
import com.scs.application.modules.wm.entity.Stock;
import com.scs.application.modules.wm.service.StockService;
import com.scs.application.modules.wm.service.TransferItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Service
public class AdjustmentServiceImpl extends BaseServiceImpl<AdjustmentMapper, Adjustment> implements AdjustmentService {
    @Resource
    private AdjustmentItemMapper adjustmentItemMapper;

    @Resource
    private AdjustmentMapper adjustmentMapper;

    @Resource
    private MatrMapper matrMapper;

    @Autowired
    private MatrUnitService matrUnitService;

    @Autowired
    private StockService stockService;

    @Autowired
    private AdjustStockService adjustStockService;

    @Autowired
    private PackTempletItemService packTempletItemService;
    @Autowired
    private TransferItemService transferItemService;
    @Autowired
    @Lazy
    private AdjustmentItemService adjustmentItemService;

    @Autowired
    private HisConfig hisConfig;

    @Override
    public boolean saveOrUpdate(Adjustment entity) {
        if (StringUtils.isBlank(entity.getAdjustKey())) {
            entity.setAdjustKey(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.ADJUST_KEY));
        }
        return super.saveOrUpdate(entity);
    }

    @Override
    protected void beforeHandleFlowChange(FlowContext flowContext, Adjustment newEntity) {
        super.beforeHandleFlowChange(flowContext, newEntity);
        String buttonKey = flowContext.getButtonKey();
        // 提交审核，不允许空明细提交
        if ("submit".equalsIgnoreCase(buttonKey)) {
            Integer count = adjustmentItemMapper.selectCount(Wrappers.<AdjustmentItem>query().eq("adjust_id", flowContext.getBusId()));
            if (count == null || count == 0) {
                throw new BusinessException("请添加明细后提交");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void afterHandleFlowChange(FlowContext flowContext, Adjustment newEntity) {
        super.afterHandleFlowChange(flowContext, newEntity);
        boolean endNode = flowContext.isEndNode();
        //1.判断是否为审核通过节点 2.若为审核通过节点，但是存在生效日期也不进行后续操作，等待生效日期再进行后续操作
        if (!endNode) {
            return;
        }
        Adjustment adjustment = flowContext.getBusEntity();
        this.ChargeChange(adjustment);
    }

    //调价单审核通过之后改价操作
    @Override
    @Transactional(rollbackFor = Exception.class)
    synchronized   public void ChargeChange(Adjustment adjustment){
        List<AdjustmentItem> adjustmentItems = adjustmentItemMapper.selectList(Wrappers.<AdjustmentItem>query().eq("adjust_id", adjustment.getId()));
        for (AdjustmentItem adjustItem : adjustmentItems) {
            Matr matr = matrMapper.selectOne(new QueryWrapper<Matr>().eq("id", adjustItem.getMatrId()));
            if (StringUtils.isBlank(adjustItem.getHisCodeAfter())) {
                adjustItem.setHisCodeAfter(matr.getHisCode());
                adjustItem.setHisPriceAfter(matr.getHisPrice());
            }
            if (StringUtils.isBlank(adjustItem.getHrpCodeAfter())) {
                adjustItem.setHrpCodeAfter(matr.getHrpCode());

            }
            if (adjustItem.getHisPriceAfter() == null){
                adjustItem.setHisPriceAfter(matr.getHisPrice());
            }
            if (adjustItem.getSkuPriceAfter() != null && adjustItem.getSkuPriceAfter() >0) {
                matr.setSkuPrice(adjustItem.getSkuPriceAfter());
            }

            matr.setHisPrice(adjustItem.getHisPriceAfter())
                    .setHrpCode(adjustItem.getHrpCodeAfter())
                    .setHisCode(adjustItem.getHisCodeAfter());
            matrMapper.updateById(matr);


            //价格未变化的
            if (adjustItem.getSkuPriceAfter() == null || adjustItem.getSkuPriceAfter() <0)  continue;
            List<MatrUnit> matrUnitList = matrUnitService.list(new QueryWrapper<MatrUnit>().eq("matr_id", adjustItem.getMatrId()));
            for (MatrUnit matrUnit : matrUnitList) {
                matrUnit.setPrice(adjustItem.getSkuPriceAfter() * matrUnit.getRate());
                matrUnitService.updateById(matrUnit);
            }

            //修改库存
            if (adjustItem.getFlagStock()) {
//                修改库存价格，数量大于0
                List<Stock> stocks =  null;
                if (adjustItem.getFlagMatr() == null || adjustItem.getFlagMatr() == false){ // 按照耗材及价格找相关库存
                    stocks = stockService.list(Wrappers.<Stock>query().eq("matr_id",matr.getId()).ne("sku_price",adjustItem.getSkuPriceAfter()).gt("sku_qty",0));
                } else {
                    stocks = adjustmentItemMapper.getNotLockStock(adjustItem.getMatrId());
                }
                if (stocks == null || stocks.size() <1) continue;
                for (Stock item : stocks) {
                    boolean success = stockService.update(Wrappers.<Stock>update()
                            .set("sku_price", adjustItem.getSkuPriceAfter())
                            .set("amount", adjustItem.getSkuPriceAfter() * item.getSkuQty())
                            .eq("id", item.getId())
                    );
                    if (success) {
                        AdjustStock adjustStock = new AdjustStock();
                        adjustStock.setName(adjustment.getRemark());
                        adjustStock.setAdjustDtlId(adjustItem.getId());
                        adjustStock.setAdjustId(adjustment.getId());
                        adjustStock.setStockId(item.getId());
                        adjustStock.setQtyAdjust(item.getSkuQty());
                        adjustStock.setSn(item.getSn());
                        adjustStock.setSkuPriceBefore(item.getSkuPrice());
                        adjustStock.setSkuPriceAfter(adjustItem.getSkuPriceAfter());
                        adjustStock.setSkuPriceChange(adjustStock.getSkuPriceAfter() - item.getSkuPrice());
                        adjustStock.setAmountAdjustSp(adjustStock.getSkuPriceChange() * item.getSkuQty());
                        adjustStock.setAmountAdjustPatient((adjustItem.getHisPriceChange() == null ? 0 :adjustItem.getHisPriceChange()) * item.getSkuQty());
                        adjustStock.setRemark(adjustment.getRemark());
                        adjustStockService.save(adjustStock);
                    }

                    //如果是一物一码，则更新对应调拨单的价格
                    if (item.getFlagOmoc() != null && item.getFlagOmoc() ) {
                        transferItemService.updatePrice(item.getId(),adjustItem.getSkuPriceAfter());
                    }
                };
            }
        };
        packTempletItemService.updateByMatrId(adjustmentItems.stream().map(AdjustmentItem::getMatrId).collect(Collectors.toList()));
    }

    /**
     *
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
   public  RestResult effectiveChange(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
       Date dateNow=new Date();
        RestResult result = RestResult.ok("操作成功");
        int changeNum=0;
        String msg=null;
       //获取所有今天生效的调价单
       List<Adjustment> adjustmentList = adjustmentMapper.selectList(Wrappers.<Adjustment>query().eq("effective_date", sdf.format(dateNow)).eq("flow_status",GlobalConsts.FLOW_SUBMIT_VALUE));
       for(Adjustment adjustment:adjustmentList){
               //判断是否有调价明细，没有明细不允许调价
               List<AdjustmentItem> adjustmentItems = adjustmentItemMapper.selectList(Wrappers.<AdjustmentItem>query().eq("adjust_id", adjustment.getId()));
               if(adjustmentItems.size()==0){
                   continue;
               }
               //将状态修改为审核通过
               adjustment.setFlowStatus("end");
               //修改调价单状态
               this.saveOrUpdate(adjustment);
               //进行调价审核通过后的后续动作
               this.ChargeChange(adjustment);
               changeNum++;
       }
       msg="共调价"+changeNum+"件耗材,生效日期为"+sdf.format(dateNow);
       result.setMsg(msg);
       return result;
   }


   // his物价调整
    /**
     * @description:
     * @author: Tai
     * @param  adjustBuildList  物价变更列表
     * @param  from             变更来源，作为调价单的备注是用
     * @param  updateMatrHis    【预留参数】 true: 更新本地的his收费价格，商品同步完，可能物价列表还没同步
     **/
    @Override
    public int buildByHisChange(List<AdjustBuildDTO> adjustBuildList,String from,Boolean updateMatrHis) {
        List<Matr> matrList = matrMapper.selectList(
                Wrappers.<Matr>query()
                        .in("his_code",adjustBuildList.stream().map(AdjustBuildDTO::getHisCodeBefore).distinct().collect(Collectors.toList()))
                        .isNotNull("his_code")
        );

        //筛选价格发生变化的
        Map<String,AdjustBuildDTO>  adjustBuildMapByHisCodeBefore =  adjustBuildList.stream().collect(Collectors.toMap(AdjustBuildDTO::getHisCodeBefore, item -> item));
        matrList = matrList.stream().filter(
                item ->
                        item.getHisCode().equals(adjustBuildMapByHisCodeBefore.get(item.getHisCode()).getHisCodeBefore())
                                && !NumberUtil.equals(UtilNum.getDouble(item.getHisPrice()),UtilNum.getDouble(adjustBuildMapByHisCodeBefore.get(item.getHisCode()).getHisPriceAfter()))
        ).collect(Collectors.toList());

        // 没有商品的不做处理
        if (ObjectUtil.length(matrList) == 0) {
            return 0;
        }

        // 一个商品生成一个调价单
        Adjustment adjustment;
        AdjustmentItem adjustmentItem;
        List<AdjustmentItem> adjustmentItemList = Lists.newArrayList();
        Date dateNow = DateUtils.now();

        Supplier spDefault = new Supplier();
        spDefault.setName("无供应商").setHrpCode("-1").setId("-1");

        adjustment = new Adjustment();
        adjustment.setAdjustKey(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.ADJUST_KEY));
        adjustment.setAdjustDate(dateNow).setAdjustType("2").setAdjustUser("系统").setRemark(from);
        if (hisConfig.getHisPriceAdjustmentConfig() != null && StringUtils.isNotBlank(hisConfig.getHisPriceAdjustmentConfig().getFlowStatus())) {
            adjustment.setFlowStatus(hisConfig.getHisPriceAdjustmentConfig().getFlowStatus());
        } else{
            // 直接审核通过
            adjustment.setFlowStatus(GlobalConsts.FLOW_END_VALUE);
        }
        this.saveOrUpdate(adjustment);
        for(Matr matr: matrList) {
            adjustmentItem = new AdjustmentItem();
            adjustmentItem.setAdjustId(adjustment.getId())
                    .setMatrId(matr.id)
                    .setMatrName(matr.getName())
                    .setMatrModel(matr.getModel())
                    .setMatrSpec(matr.getSpec())
                    .setSupplierId(matr.getSupplierId())
                    .setSupplierName(matr.getSupplierName())
                    .setSkuPriceBefore(matr.getSkuPrice())
                    .setSkuPriceAfter(adjustBuildMapByHisCodeBefore.get(matr.getHisCode()).getHisPriceAfter())
                    .setHisPriceBefore(adjustBuildMapByHisCodeBefore.get(matr.getHisCode()).getHisPriceBefore())
                    .setHisPriceAfter(adjustBuildMapByHisCodeBefore.get(matr.getHisCode()).getHisPriceAfter())
                    .setHisCodeBefore(adjustBuildMapByHisCodeBefore.get(matr.getHisCode()).getHisCodeBefore())
                    .setHisCodeAfter(adjustBuildMapByHisCodeBefore.get(matr.getHisCode()).getHisCodeAfter());
            adjustmentItem.setSkuPriceChange(adjustmentItem.getSkuPriceAfter() - adjustmentItem.getSkuPriceBefore());
            adjustmentItem.setHisPriceChange(adjustmentItem.getHisPriceAfter() - adjustmentItem.getHisPriceBefore());
            if (StringUtils.isBlank(adjustmentItem.getSupplierId())) {
                adjustmentItem.setSupplierId(spDefault.getId()).setSupplierName(spDefault.getName());
            }

            // 是否更新库存
            if (hisConfig.getHisPriceAdjustmentConfig() != null && hisConfig.getHisPriceAdjustmentConfig().getFlagStock() != null) {
                adjustmentItem.setFlagStock(hisConfig.getHisPriceAdjustmentConfig().getFlagStock());
            }else {
                adjustmentItem.setFlagStock(true);
            }
            adjustmentItem.setFlagMatr(false);
            adjustmentItemList.add(adjustmentItem);
        }
        adjustmentItemService.saveBatch(adjustmentItemList);

        // 直接改价
        if (adjustment.getFlowStatus().equals(GlobalConsts.FLOW_END_VALUE)) {
            this.ChargeChange(adjustment);
        }
        return  1;
    }


    /**
     * @description: 供应商平台价格变更
     * @author: Tai
     * @param  adjustBuildList  物价变更列表
     * @param  from             变更来源，作为调价单的备注是用
     * @param  updateMatrHis    【预留参数】 true: 更新本地的his收费价格，商品同步完，可能物价列表还没同步
     **/
    @Override
    public String buildBySpChange(List<AdjustBuildScpDTO> adjustBuildList, String from, Boolean updateMatrHis) {
        if (
                hisConfig.getScpPriceAdjustmentConfig() != null
                        && hisConfig.getScpPriceAdjustmentConfig().getDisabled() != null
                        && hisConfig.getScpPriceAdjustmentConfig().getDisabled()
        ) {
            logger.error("buildBySpChange 供应商平台价格变更已禁用");
            return "供应商平台价格变更已禁用";
        }
        List<Matr> matrList = matrMapper.selectList(
                Wrappers.<Matr>query()
                        .in("id",adjustBuildList.stream().map(AdjustBuildScpDTO::getMatrId).distinct().collect(Collectors.toList()))
        );

        //筛选价格发生变化的
        Map<String,AdjustBuildScpDTO>  adjustBuildMapByMatrId =  adjustBuildList.stream().collect(Collectors.toMap(AdjustBuildScpDTO::getMatrId, item -> item));
        matrList = matrList.stream().filter(
                item ->
                        item.getId().equals(adjustBuildMapByMatrId.get(item.getId()).getMatrId())
                                && !NumberUtil.equals(item.getSkuPrice(),adjustBuildMapByMatrId.get(item.getId()).getSkuPriceAfter())
        ).collect(Collectors.toList());

        // 没有商品的不做处理
        if (ObjectUtil.length(matrList) == 0) {
            return "";
        }

        // 一个商品生成一个调价单
        Adjustment adjustment;
        AdjustmentItem adjustmentItem;
        List<AdjustmentItem> adjustmentItemList = new ArrayList<>();
        Date dateNow = DateUtils.now();

        adjustment = new Adjustment();
        adjustment.setAdjustKey(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.ADJUST_KEY));
        adjustment.setAdjustDate(dateNow).setAdjustType("3").setAdjustUser("系统").setRemark(from);

        if (hisConfig.getScpPriceAdjustmentConfig() != null && StringUtils.isNotBlank(hisConfig.getScpPriceAdjustmentConfig().getFlowStatus())) {
            adjustment.setFlowStatus(hisConfig.getScpPriceAdjustmentConfig().getFlowStatus());
        } else{
            // 直接审核通过
            adjustment.setFlowStatus(GlobalConsts.FLOW_END_VALUE);
        }
        this.saveOrUpdate(adjustment);

        Supplier spDefault = new Supplier();
        spDefault.setName("无供应商").setHrpCode("-1").setId("-1");
        for(Matr matr: matrList) {
            adjustmentItem = new AdjustmentItem();
            adjustmentItem.setAdjustId(adjustment.getId())
                    .setMatrId(matr.id)
                    .setMatrName(matr.getName())
                    .setMatrModel(matr.getModel())
                    .setMatrSpec(matr.getSpec())
                    .setSupplierId(matr.getSupplierId())
                    .setSupplierName(matr.getSupplierName())
                    .setHisPriceBefore(matr.getHisPrice())
                    .setHisCodeBefore(matr.getHisCode())
                    .setHisCodeAfter(matr.getHisCode());

            adjustmentItem.setSkuPriceBefore(adjustBuildMapByMatrId.get(matr.getId()).getSkuPriceBefore());
            adjustmentItem.setSkuPriceAfter(adjustBuildMapByMatrId.get(matr.getId()).getSkuPriceAfter());
            adjustmentItem.setHisPriceAfter(adjustmentItem.getSkuPriceAfter());
            adjustmentItem.setSkuPriceChange(adjustmentItem.getSkuPriceAfter() - adjustmentItem.getSkuPriceBefore());
            adjustmentItem.setHisPriceChange(adjustmentItem.getHisPriceAfter() - adjustmentItem.getHisPriceBefore());
            if (StringUtils.isBlank(adjustmentItem.getSupplierId())) {
                adjustmentItem.setSupplierId(spDefault.getId()).setSupplierName(spDefault.getName());
            }
            // 是否更新库存
            if (hisConfig.getScpPriceAdjustmentConfig() != null && hisConfig.getScpPriceAdjustmentConfig().getFlagStock() != null) {
                adjustmentItem.setFlagStock(hisConfig.getScpPriceAdjustmentConfig().getFlagStock());
            }else {
                adjustmentItem.setFlagStock(true);
            }
            adjustmentItem.setFlagMatr(false);
            adjustmentItemList.add(adjustmentItem);
        }

        adjustmentItemService.saveBatch(adjustmentItemList);
        // 直接改价
        if (adjustment.getFlowStatus().equals(GlobalConsts.FLOW_END_VALUE)) {
            this.ChargeChange(adjustment);
        }
        return "生成调价单:" + adjustment.getAdjustKey();
    }
}
